{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e0d9703a",
   "metadata": {},
   "source": [
    "## GreyWolf Optimizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "4cb54a3f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: numpy in ./venv/lib/python3.8/site-packages (1.20.3)\n",
      "Requirement already satisfied: matplotlib in ./venv/lib/python3.8/site-packages (3.4.2)\n",
      "Requirement already satisfied: pillow>=6.2.0 in ./venv/lib/python3.8/site-packages (from matplotlib) (8.2.0)\n",
      "Requirement already satisfied: python-dateutil>=2.7 in ./venv/lib/python3.8/site-packages (from matplotlib) (2.8.1)\n",
      "Requirement already satisfied: kiwisolver>=1.0.1 in ./venv/lib/python3.8/site-packages (from matplotlib) (1.3.1)\n",
      "Requirement already satisfied: numpy>=1.16 in ./venv/lib/python3.8/site-packages (from matplotlib) (1.20.3)\n",
      "Requirement already satisfied: cycler>=0.10 in ./venv/lib/python3.8/site-packages (from matplotlib) (0.10.0)\n",
      "Requirement already satisfied: pyparsing>=2.2.1 in ./venv/lib/python3.8/site-packages (from matplotlib) (2.4.7)\n",
      "Requirement already satisfied: six>=1.5 in ./venv/lib/python3.8/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n"
     ]
    }
   ],
   "source": [
    "!pip install numpy\n",
    "!pip install matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b1426cdd",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "47bf2a96",
   "metadata": {},
   "outputs": [],
   "source": [
    "class wolf:\n",
    "    \n",
    "    def __init__(self, dim):\n",
    "        self.position = 100 * np.random.rand(dim)\n",
    "        self.obj_score = float('inf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0d95cbbb",
   "metadata": {},
   "outputs": [],
   "source": [
    "def GWO(obj_fun, soln_dim, wolves_n, iter_n):\n",
    "    \n",
    "    # obj_fun   - objective function to be minimized\n",
    "    # soln_dim  - dimension of solution vector\n",
    "    # wolves_n  - no. of searching wolves\n",
    "    # iter_n    - no of iterations\n",
    "    \n",
    "    wolves = []\n",
    "    \n",
    "    # 1] Initialize positions of wolves randomly\n",
    "    \n",
    "    for i in range(wolves_n):\n",
    "        w = wolf(soln_dim)\n",
    "        #print(w.position)\n",
    "        wolves.append(w)\n",
    "    \n",
    "    alpha , beta, delta = wolves[:3]\n",
    "    \n",
    "    score_history = {\n",
    "        'alpha' : [],\n",
    "        'beta' : [],\n",
    "        'delta' : []\n",
    "    }\n",
    "    \n",
    "    # 2] Loop 3-4  iter_n times\n",
    "    \n",
    "    for i in range(iter_n):\n",
    "        \n",
    "    #   3] Calculate objective function for all wolves and find best 3 alpha, beta & gamma\n",
    "        \n",
    "        for w in wolves:\n",
    "            w.obj_score = obj_fun(w.position)\n",
    "            \n",
    "            if w.obj_score <= alpha.obj_score:\n",
    "                delta = beta\n",
    "                beta = alpha\n",
    "                alpha = w\n",
    "            \n",
    "            elif w.obj_score <= beta.obj_score:\n",
    "                delta = beta\n",
    "                beta = w\n",
    "                \n",
    "            elif w.obj_score <= delta.obj_score:\n",
    "                delta = w\n",
    "                \n",
    "        score_history['alpha'].append(alpha.obj_score)\n",
    "        score_history['beta'].append(beta.obj_score)\n",
    "        score_history['delta'].append(delta.obj_score)\n",
    "        \n",
    "        \n",
    "    #   4] Update positions of rest of wolves based on GWO mathematical formula\n",
    "    \n",
    "        # a decreases linearly from 2 to 0 as iteration proceeds\n",
    "        a = 2 * (1 - (i/iter_n))\n",
    "        \n",
    "        for w in wolves:\n",
    "            \n",
    "            # r1 & r2 are random vectors in [0, 1]\n",
    "            r1 = np.random.rand(soln_dim)\n",
    "            r2 = np.random.rand(soln_dim)\n",
    "            \n",
    "            A1 = a * ((2 * r1) - 1)\n",
    "            C1 = 2 * r2\n",
    "            \n",
    "            D_alpha = abs((C1 * alpha.position) - w.position) \n",
    "            X1 = alpha.position - (A1 * D_alpha)\n",
    "            \n",
    "            \n",
    "            r1 = np.random.rand(soln_dim)\n",
    "            r2 = np.random.rand(soln_dim)\n",
    "            \n",
    "            A2 = a * ((2 * r1) - 1)\n",
    "            C2 = 2 * r2\n",
    "\n",
    "            D_beta = abs((C2 * beta.position) - w.position) \n",
    "            X2 = beta.position - (A2 * D_beta)\n",
    "            \n",
    "            \n",
    "            r1 = np.random.rand(soln_dim)\n",
    "            r2 = np.random.rand(soln_dim)\n",
    "            \n",
    "            A3 = a * ((2 * r1) - 1)\n",
    "            C3 = 2 * r2\n",
    "\n",
    "            D_delta = abs((C3 * delta.position) - w.position) \n",
    "            X3 = delta.position - (A3 * D_delta)\n",
    "            \n",
    "            w.position = (X1 + X2 + X3)/3\n",
    "    \n",
    "    # 5] Return best solution (alpha)\n",
    "    \n",
    "    return alpha, score_history\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "69814e82",
   "metadata": {},
   "outputs": [],
   "source": [
    "def dummy_obj_fun(sol):\n",
    "    return sum(sol*sol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2c67a160",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-3.68987639e-05,  1.84974228e-04,  3.37788019e-04])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "soln_dim = 3\n",
    "wolves_n = 150\n",
    "iter_n = 10\n",
    "\n",
    "best, history = GWO(dummy_obj_fun, soln_dim=soln_dim, wolves_n=wolves_n, iter_n=iter_n)\n",
    "best.position"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "2597d38d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(np.array(history['alpha']) ,label='alpha')\n",
    "plt.plot(np.array(history['beta']), label='beta')\n",
    "plt.plot(np.array(history['delta']), label='delta')\n",
    "plt.xlabel(\"Iteration No\")\n",
    "plt.ylabel(\"Fitness Score\")\n",
    "plt.title('Progress')\n",
    "plt.grid()\n",
    "plt.legend()\n",
    "plt.savefig(\"graph\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "536d7289",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[87.74442734164452, 23.397306594807066, 3.2335240625188124, 0.5012183489827489, 0.06500977079342869, 0.017754978590692222, 0.0031355198765169656, 3.3276893984678424e-05, 4.694388565790032e-06, 2.723885183828924e-07]\n",
      "[217.05450581531719, 23.819329169207947, 5.388540891490693, 1.9230078190781792, 0.0993353267686046, 0.019920295184303854, 0.003277329129977312, 0.0001497491807366053, 9.269747695891768e-06, 6.181186643734202e-07]\n",
      "[276.45829393630754, 25.661886805881903, 6.778956305007788, 2.464989970474093, 0.3896419133645417, 0.020277860181780575, 0.0033359157386731097, 0.00016502192837053654, 1.7173148408796357e-05, 7.72185319994031e-07]\n"
     ]
    }
   ],
   "source": [
    "print(history['alpha'])\n",
    "print(history['beta'])\n",
    "print(history['delta'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e312522f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
